#include "ParallaxLayer.h"
#include "TextureManager.h"
#include <iostream>
#include "GameEngine.h"
using namespace std;
// Constructor a
ParallaxLayer::ParallaxLayer(const std::string &file, float factor_x, bool repeat_x, float offset_x, 
	float factor_y, bool repeat_y, float offset_y,bool move,float vel,int dir,bool fallowViewX,bool fallowViewY,bool fullScreen){
	const sf::Image &tex = TextureManager::GetInstance().GetTexture(file);
	SetImage(tex);	
	// calculamos el ancho y alto de la imagen, esto
	// nos va a servir para evitar desbordes en el desplazamiento
	ancho_img=  tex.GetWidth();
	alto_img=   tex.GetHeight();	
	// inicializamos las variables internas
	despl_x=despl_y=0;
	this->factor_x=factor_x;
	this->factor_y=factor_y;
	this->repeat_x=repeat_x;
	this->repeat_y=repeat_y;
	this->offset_x=offset_x;
	this->offset_y=offset_y;
	this->move=move;
	this->vel=vel;
	this->dir=dir;
	this->fallowViewX=fallowViewX;
	this->fallowViewY=fallowViewY;
	this->fullScreen=fullScreen;
	// seleccionamos la textura y habilitamos la repeticion
	// segun corresponda
	tex.Bind();
	if(repeat_x)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	if(repeat_y)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	
	// ajustamos la posicion de la capa
	Sprite::SetPosition(offset_x, offset_y);
}
// Constructor b
ParallaxLayer::ParallaxLayer(const std::string &file, const std::vector<float> &settings,float zonax,float zonay){

	std::vector< float > ps = settings;
	const sf::Image &tex = TextureManager::GetInstance().GetTexture(file);
	SetImage(tex);	
	// calculamos el ancho y alto de la imagen, esto
	// nos va a servir para evitar desbordes en el desplazamiento
	ancho_img=  tex.GetWidth();
	alto_img=   tex.GetHeight();	
	// inicializamos las variables internas
	despl_x=despl_y=0;
	this->factor_x=ps[0];	
	this->repeat_x=ps[1];
	this->offset_x=ps[2];
	this->factor_y=ps[3];	
	this->repeat_y=ps[4];	
	this->offset_y=ps[5];
	this->move=ps[6];
	this->vel=ps[7];
	this->dir=ps[8];
	this->fallowViewX=ps[9];
	this->fallowViewY=ps[10];
	this->fullScreen=ps[11];
	
	//---*Si la Textura tiene que ocupar todo el espacio del view:
	/*
	if(fullScreen){
	//---*Si el Parallax es menos ancho que la ventana de juego:
	float anchoZona=zonax;
	float altoZona=zonay;	

	if(ancho_img < anchoZona){
	//---*Lo hacemos igual de ancho
    float diff= anchoZona/ancho_img ;
	SetScale(diff,0);
	}
	else{
    //---*Lo hacemos igual de ancho
    float diff= anchoZona/ancho_img ;
	SetScale(diff,0) ;

	}

	if(alto_img < altoZona){
	//---*Lo hacemos igual de alto
	float diff= altoZona/alto_img ;
	SetScale(0,diff);
	}
	else{
	//---*Lo hacemos igual de alto
	float diff= altoZona/alto_img ;
	SetScale(0,diff);

	}


	ancho_img=  GetSize().x;
	alto_img=   GetSize().y;

	}
	*/


	// seleccionamos la textura y habilitamos la repeticion
	// segun corresponda
	tex.Bind();
	if(repeat_x)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	if(repeat_y)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	
	// ajustamos la posicion de la capa
	Sprite::SetPosition(offset_x, offset_y);
}
// Permite mover la capa segun el desplazamiento del personaje
void ParallaxLayer::Move(float dx, float dy){
	// para x
	if(repeat_x){
		// si debemos desplazar la textura simplemente
		// incrementamos la variable despl_x y la mantenemos
		// limitada para evitar desbordes
		despl_x+=factor_x*dx;
		if(factor_x>0 && despl_x>ancho_img) despl_x-=ancho_img;
		else if(factor_x<0 && despl_x<-ancho_img) despl_x+=ancho_img;
	}else{
		// de lo contrario movemos el sprite
		Sprite::Move(factor_x*dx, 0);
	}
	
	// para y
	if(repeat_y){
		// si debemos desplazar la textura simplemente
		// incrementamos la variable despl_y y la mantenemos
		// limitada para evitar desbordes
		despl_y+=factor_y*dy;
		if(factor_y>0 && despl_y>alto_img) despl_y-=alto_img;
		else if(factor_y<0 && despl_y<-alto_img) despl_y+=alto_img;
	}else{
		// de lo contrario movemos el sprite
		Sprite::Move(0, factor_y*dy);
	}
}


// Permite mover la capa dado un lapso de tiempo dt
void ParallaxLayer::Move(float dt){


	switch(dir)
	{
	case 1:	   Move(dt*-vel,0.0f);break;
	case 2 :   Move(dt*vel,0.0f);break;
	case 3:    Move(0.0f,dt*-vel);break;
	case 4:    Move(0.0f,dt*vel);break;		
	}
}


// Dibuja la capa
void ParallaxLayer::Draw(sf::RenderWindow &w){
	// selecciona y guarda la matriz de textura
	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	// aplicamos la transformacion y dibujamos
	glLoadIdentity();
	glTranslatef(despl_x,despl_y,0);
	w.Draw(*this);
	// restauramos la matriz de textura
	glMatrixMode(GL_TEXTURE);
	glPopMatrix();	
}


// Permite ajustar la capa a la vista para usar scrolling
void ParallaxLayer::SetPosition(sf::View &v){

	float x=offset_x;
	float y=offset_y;
	if(fallowViewX)x=offset_x+v.GetRect().Left;
	if(fallowViewY)y=offset_y+v.GetRect().Top;

	Sprite::SetPosition(x,y);
}


